import config from '@/common/config';
//import MQTT from 'paho-mqtt';
import moment from 'moment';
import store from "@/store/index.js"
import {
	DB,
	device,
	user,
	http,
	tools,
	MQTT
} from '@/common/framework';


export default class PushMsg {
	constructor() {
		this.db = DB.init("push-msg");
		this.appId = config.appId;
		this.baseApi = config.msgPush.webApi + '/' + this.appId;
		this.client = null;
		this.curUserInfo = user.getUserInfo();
		this.IsConnent = false;
		this.clientInfo = {
			token: ''
		};
		//#ifdef APP-PLUS || APP-PLUS-NVUE
		this.clientInfo = plus.push.getClientInfo();
		this.clientInfo.uniPushId=this.clientInfo.clientid;
		//#endif
		this.devCode = device.getDevCode();
	
	}

	static init() {
		let pushClient = store.getters.pushClient;
		
		if (!pushClient) {
			pushClient = new this();
			store.commit('setPushClient', pushClient);
		}
		return pushClient;
	
	}



	/**
	 * 初始化Push
	 */
	async initPush() {
		let ret = await this.sign();
		if (ret && ret.Result == 1) {
			console.log("initPush", JSON.stringify(ret));
			await this.connect(ret.Data.clientId, ret.Data.connectId);
			if (this.curUserInfo.userId != '') {
				await this.setClientInfo(this.curUserInfo.userRealName, this.curUserInfo.headerImg);
			}
		}
		return true;
	}

	/**
	 * 向推送服务端签到
	 */
	sign() {
		return new Promise(async (a, b) => {
			try {
				let appInfo={
					appId:config.appId,
					packageName: config.packageName,
					geTui:JSON.stringify(config.msgPush.getTui),
					huaWei:JSON.stringify(config.msgPush.huaWei),
					oppo:JSON.stringify(config.msgPush.oppo),
					vivo:JSON.stringify(config.msgPush.vivo),
					xiaoMi:JSON.stringify(config.msgPush.xiaoMi)
				};
				
				let postData = {
					devType: device.getDevType(),
					devCode: this.devCode,
					label: 'message',
					appInfo:JSON.stringify(appInfo),
					deviceToken: this.clientInfo.token
					
				};
				console.log(JSON.stringify(postData));
				let ret = await http.post(this.baseApi + "/client/sign", postData);
				if (ret && ret.Result == 1) {
					this.clientInfo.clientid = ret.Data.clientId;
					this.clientInfo.connectid = ret.Data.connectId;
					user.setPushClientInfo(ret.Data.clientId, ret.Data.connectId);
					store.commit('setPushClient', this);
					a(ret);
				} else {
					a(false);
				}
			} catch (err) {
				console.log(JSON.stringify(err));
				b(err);
			}
		})
	}

	/**
	 * 连接服务器
	 * @param {Object} clientId
	 * @param {Object} connectId
	 */
	connect(clientId, connectId) {
		let self = this;
		return new Promise((a, b) => {
			self.client = new MQTT.Client(config.msgPush.mqttHost, Number(config.msgPush.mqttWebSocketPort), connectId);

			self.client.connect({
				userName: "",
				password: "",
				reconnect: false,
				cleanSession: false,
				onSuccess: () => {
					console.log('推送服务器连接成功');
					self.IsConnent = true;
					store.commit('setPushClient', self);
					if (this.curUserInfo.userId != "") {
						self.setAlias(self.curUserInfo.userId);
					}

					self.bindEvent(clientId, connectId);
					a(self.client);
				},
				onFailure: (errorCode) => {
					console.log("推送服务器连接失败");
					self.disConnent();
					self.IsConnent = false;
					store.commit('setPushClient', self);

				}
			});
		});

	}

	/**
	 * 绑定事件
	 * @param {Object} clientId
	 * @param {Object} connectId
	 */
	bindEvent(clientId, connectId) {
		this.client.onConnected = function() {
			this.IsConnent = true;
			this.client.subscribe(clientId, {
				qos: 0,
			});
			this.client.subscribe(connectId, {
				qos: 0,
			});

			if (this.curUserInfo.userId != "") {
				this.setAlias(this.curUserInfo.userId);
			}

		}.bind(this);

		this.client.onConnectionLost = function(responseObject) {
			this.IsConnent = false;
			console.log("推送服务连接断开");
			store.commit('setPushClient', this);
			// setTimeout(() => {
			
			// 	this.connect(clientId, connectId);
			// }, 1000);


		}.bind(this);

		this.client.onMessageArrived = async function(payload) {
			try{
				let msgData = JSON.parse(payload.payloadString);
				console.log('onMessageArrived', msgData);
				let t_id = tools.SHA1(msgData.sender.id + this.curUserInfo.userId);
				if (msgData.msgType == 'group') {
					t_id = tools.SHA1(msgData.target.id + this.curUserInfo.userId);
				}
				
				if (msgData.preload.cmd) { //如果cmd存在 ， 调用本地方法
					switch (msgData.preload.cmd[0]) {
						case 'updateGroupName':
							await this.updateGroupName(msgData.preload.cmd[1], msgData.preload.cmd[2]);
							break;
						case 'removeGroup': //移除小组
							let ret = await this.getTopicIdBySenderId(msgData.preload.cmd[1]);
							if (ret) {
								this.removeTopic(ret).then(() => {
									uni.$emit('clearMessagesUnreadStatus', {});
								});
							}
							break;
						case 'joinGroup': //加入小组
							break;
					}
					return;
				}
				
				await this.saveMsgToDb(t_id, msgData);
				uni.$emit('onMessageArrived', msgData);
				
				if(store.getters.appState=='app-show'){
					this.playSound();
				}
				
			}catch(err){
				console.error(err);
			}
			
			

		}.bind(this);
	}
	
	
	playSound() {
		const innerAudioContext = uni.createInnerAudioContext();
		innerAudioContext.autoplay = true;
		innerAudioContext.src = "/static/ring/ru.wav";
		innerAudioContext.onPlay(() => {
			
		});
	}


	saveMsgToDb(t_id, msgData) {
		return new Promise(async (a, b) => {
			try {
				let dialogueTableName = "dialogue_" + t_id;
				
				let ret = await this.db.selectSql("select count(*) as count from topic where t_id='" + t_id + "'");
				if (ret[0].count == 0) { //不存在，新建
					
					let sql =
						"insert into topic (t_id,t_type,t_userId,t_senderId,t_title,t_content,t_icon,t_time,t_unReadCount,t_isTop,t_msgType) values ('" +
						t_id + "'," + msgData.preload.type + ",'" + this.curUserInfo.userId + "','" + msgData.sender.id + "','" +
						msgData.sender.name + "','" + msgData.notification.content + "','" + msgData.sender.icon + "'," +
						msgData.dateTime + ",0,0,'" + msgData.msgType + "')";

					if (msgData.msgType == 'group') {
						sql =
							"insert into topic (t_id,t_type,t_userId,t_senderId,t_title,t_content,t_icon,t_time,t_unReadCount,t_isTop,t_msgType) values ('" +
							t_id + "'," + msgData.preload.type + ",'" + this.curUserInfo.userId + "','" + msgData.target.id + "','" +
							msgData
							.target.name + "','" + tools.fixLen(msgData.notification.content, 20) + "','" + msgData.target.icon +
							"'," + msgData.dateTime + ",0,0,'" + msgData.msgType + "')";
					}
					
					await this.db.executeSql(sql);
				} else { //存在，更新
				;
					let curTopicId = uni.getStorageSync('curTopicId');
					await this.db.executeSql("update topic set t_title='"+msgData.sender.name+"' ,t_icon='"+msgData.sender.icon+"',   t_content='" + tools.fixLen(msgData.notification.content, 20) + "',t_time=" + msgData.dateTime + " where t_id='" + t_id + "'");
					if (curTopicId != t_id) { //设置未读数量
					
						let sql = "update topic set   t_unReadCount=t_unReadCount+1 where t_id='" + t_id + "'";
						
						await this.db.executeSql(sql);
						
					}
				}
				
				//创建对话表
				//#ifdef H5
				
				//#endif
				
				let createTableSql="create table if not exists " + dialogueTableName +" (d_id INTEGER PRIMARY KEY AUTOINCREMENT, d_userId NVARCHAR(36), d_userName NVARCHAR(50),d_userIcon NVARCHAR(100), d_direct NVARCHAR(10),  d_content TEXT, d_time INTEGER)";
				// let createTableSql="create table goods(_id integer primary key autoincrement,name text,price real);";
				await this.db.executeSql(createTableSql);
				
				let content = encodeURIComponent(JSON.stringify(msgData.preload));
				
				let direct = "";
				let _data = {};
				if (msgData.preload.isSendToMe) {
					_data = {
						direct: 'send',
						sender: {
							id: msgData.target.id,
							name: msgData.target.name,
							icon: msgData.target.icon
						}
					};
				} else {
					_data = {
						direct: 'receive',
						sender: {
							id: msgData.sender.id,
							name: msgData.sender.name,
							icon: msgData.sender.icon
						}
					};
				}
				console.log("_data",_data);
				await this.db.executeSql("insert into " + dialogueTableName +
					" (d_userId,d_userName,d_userIcon,d_direct,d_content,d_time) values ('" + _data.sender.id + "','" + _data.sender
					.name + "','" + _data.sender.icon + "','" + _data.direct + "','" + content + "'," + msgData.dateTime + ")");
					
				a();
			} catch (err) {
				console.error(err);
				b(err);
			}
		})
	}

	/**
	 * 断开连接
	 */
	disConnent() {
		console.log('disConnent');
		if (this.client) {
			this.client.disconnect();
			this.IsConnent = false;
		}
	}

	/**
	 * 设置客户端信息
	 * @param {Object} userName
	 * @param {Object} headerPic
	 */
	setClientInfo(userName, headerPic) {
		return new Promise((a, b) => {
			let postData = {
				clientId: this.clientInfo.clientid,
				userName: userName,
				headerPic: headerPic,
				packageName: config.packageName,
				deviceToken: this.clientInfo.token,
				uniPushId:this.clientInfo.uniPushId
			};
			
			user.setPushClientInfo(this.clientInfo.clientid, this.clientInfo.connectid);
			http.post(this.baseApi + "/client/setInfo", postData).then(function(ret, statusCode) {
				//console.log('setClientInfo',ret)
				a(ret, statusCode);
			}).catch(err => {
				b(err);
			})
		})
	}

	/**
	 * 获取客户端信息
	 * @param {Object} clientId
	 */
	getClientInfo(clientId) {
		let postData = {
			clientId: this.clientInfo.clientid || clientId
		};
		return http.post(this.baseApi + "/client/getInfo", postData);
	}

	/**
	 * 设置别名
	 * @param {Object} alias
	 */
	setAlias(alias) {
		if(!alias || alias=='') return;
		return new Promise((a, b) => {
			let postData = {
				clientId: this.clientInfo.clientid,
				alias: alias
			};
			http.post(this.baseApi + "/alias/set", postData).then(function(ret, statusCode) {
				//console.log("设置别名成功",ret);
				a(ret, statusCode);
			}).catch(err => {
				b(err);
			})
		})
	}

	removeAlias() {
		return new Promise((a, b) => {
			let postData = {
				clientId: this.clientInfo.clientid
			};
			http.post(this.baseApi + "/alias/Remove", postData).then(function(ret, statusCode) {
				console.log("移除别名成功");
				a(ret, statusCode);
			}).catch(err => {
				b(err);
			})
		})
	};

	addTags(tags) {
		return new Promise((a, b) => {
			let postData = {
				clientId: this.clientInfo.clientid,
				tags: tags
			};
			http.post(this.baseApi + "/tags/add", postData).then(function(ret, statusCode) {
				a(ret, statusCode);
			}).catch(err => {
				b(err);
			})
		})
	};

	setTags(tags) {
		return new Promise((a, b) => {
			let postData = {
				clientId: this.clientInfo.clientid,
				tags: tags
			};
			http.post(this.baseApi + "/tags/set", postData).then(function(ret, statusCode) {
				a(ret, statusCode);
			}).catch(err => {
				b(err);
			})
		})
	};

	removeTags(tags) {
		return new Promise((a, b) => {
			let postData = {
				clientId: this.clientInfo.clientid,
				tags: tags
			};
			http.post(this.baseApi + "/tags/remove", postData).then(function(ret, statusCode) {
				a(ret, statusCode);
			}).catch(err => {
				b(err);
			})
		})
	};

	sendMsg(msgData) {
		return new Promise((a, b) => {
			let postData = {
				msgData: JSON.stringify(msgData)
			};
			http.post(this.baseApi + "/msg/send", postData).then(function(ret, statusCode) {
				a(ret, statusCode);
			}).catch(err => {
				b(err);
			})
		})
	}

	/**
	 * 发送系统消息
	 * @param {Object} targetAliasArray 别名数组
	 * @param {Object} type //消息类型  11：工作待办 12：通知公告 13：系统消息
	 * @param {Object} label //消息类型下的二级分类
	 * @param {Object} title //标题
	 * @param {Object} content//内容
	 * @param {Object} msgId // 目标内容ID
	 */
	sendSystemMsg(targetAliasArray, type, label, title, content, msgId) {
		return new Promise((a, b) => {
			let msgData = {
				targets: targetAliasArray,
				type: type,
				label: label,
				title: title,
				content: content,
				msgId: msgId
			};
			let postData = {
				msgData: JSON.stringify(msgData)
			};
			http.post(this.baseApi + "/msg/sendSystemMsg", postData).then(function(ret, statusCode) {
				a(ret, statusCode);
			}).catch(err => {
				b(err);
			})
		})
	}

	/**
	 * 发送消息给用户
	 * @param {Object} senderAlias
	 * @param {Object} targetAlias
	 * @param {Object} preload
	 * @param {Object} isOneToOneChat
	 */
	sendMsgToUser(senderAlias, targetAlias, preload, isOneToOneChat) {
		return new Promise((a, b) => {
			let msgData = {
				sender: senderAlias,
				targetAlias: targetAlias,
				preload: preload
			};
			console.log(msgData);
			let postData = {
				msgData: JSON.stringify(msgData)
			};
			http.post(this.baseApi + "/msg/sendUserMsg", postData).then(function(ret, statusCode) {
				a(ret, statusCode);
			}).catch(err => {
				b(err);
			})
			if (isOneToOneChat) {
				preload.isSendToMe = 1;
				this.sendMsgToUser(targetAlias[0], senderAlias, preload, false);
			}

		})
	}

	/**
	 * 发送群组消息
	 * @param {Object} senderAlias
	 * @param {Object} groupId
	 * @param {Object} preload
	 */
	async sendMsgToGroup(senderAlias, groupId, preload) {
		let msgData = {
			sender: senderAlias,
			groupId: groupId,
			preload: preload
		};
		let postData = {
			msgData: JSON.stringify(msgData)
		};
	
		return await http.post(this.baseApi + "/msg/sendUserMsg", postData);
	}

	removeTopic(id) {
		let tabelName = "dialogue_" + id;
		let sqls = [
			"delete from topic where t_id='" + id + "'",
			"drop table " + tabelName
		];
		return this.db.executeSql(sqls);
	}

	clearDialogue(topId) {
		let tabelName = "dialogue_" + topId;
		return this.db.executeSql("delete from " + tabelName + "");
	}

	clearAllDialogue() {
		return new Promise(async (a, b) => {
			try {
				let topicItems = await this.db.selectSql("select t_id from topic where t_userId='" + this.curUserInfo.userId +
					"'");
				if (topicItems) {
					for (let i = 0; i < topicItems.length; i++) {
						let tabelName = "dialogue_" + topicItems[i].t_id;
						await this.db.executeSql("drop table if  exists " + tabelName + "");
					}
					await this.db.executeSql("delete from topic where t_userId='" + this.curUserInfo.userId + "'");
					a(true);
				} else {
					a(true);
				}

			} catch (err) {
				b(err);
			}
		})
	}

	setTopicIsTop(topicId,state) {
		return this.db.executeSql("update topic set t_isTop="+state+" where t_id='" + topicId + "'");
	}
	
	getTopicUnReadCount(topicId){
		try{
			let findFilter="t_userId = '" + this.curUserInfo.userId + "'";
			if(topicId){
				findFilter=" and t_id = '"+topicId+"'";
			}
			let sql=`select SUM(t_unReadCount) as count from topic where ${findFilter}`;
			let ret = this.db.selectSql(sql);
			return ret;
		}catch(err){
			console.log("getTopicUnReadCount" , err);
		}
		
		
	}

	getTopicIdBySenderId(sendId) {
		return this.db.selectSql("select * from topic where t_senderId='" + sendId + "'");
	}

	async getTopicInfo(topicId) {
		let ret = await this.db.selectSql("select * from  topic where t_id='" + topicId + "'");
		if(ret){
			return ret[0];
		}
		return null;
	}


	async createGroup(groupName, createAlias, aliasItems) {
		return new Promise(async (a, b) => {
			try {
				let groupInfo = {};
				let postData = {
					groupName: groupName,
					createAlias: createAlias,
					aliasItems: aliasItems.join(',')
				};
				let ret =await http.post(this.baseApi + "/group/add", postData);
				groupInfo = ret.Data;
				if (groupInfo) {
					let t_id = tools.SHA1(groupInfo.id + this.curUserInfo.userId);
					let dateTime = moment().unix();
					let sql =
						"insert into topic (t_id,t_type,t_userId,t_senderId,t_title,t_content,t_icon,t_time,t_unReadCount,t_isTop,t_msgType) values ('" +
						t_id + "',10,'" + this.curUserInfo.userId + "','" + groupInfo.id + "','" + groupInfo.name + "','','" +
						groupInfo.icon + "'," + dateTime + ",0,0,'group')";
					await this.db.executeSql(sql);
					
					let dialogueTableName = "dialogue_" + t_id;
					let createTableSql="create table if not exists " + dialogueTableName +" (d_id INTEGER PRIMARY KEY AUTOINCREMENT, d_userId NVARCHAR(36), d_userName NVARCHAR(50),d_userIcon NVARCHAR(100), d_direct NVARCHAR(10),  d_content TEXT, d_time INTEGER)";
					// let createTableSql="create table goods(_id integer primary key autoincrement,name text,price real);";
					await this.db.executeSql(createTableSql);
				}
				// uni.$emit('onMessageArrived', {});
				a(groupInfo);
			} catch (err) {
				b(err);
			}
		})
	}

	getGroupInfo(groupId) {
		return this.db.executeSql("update topic set t_title='" + groupName + "' where t_senderId='" + groupId + "'")
	}

	updateGroupName(groupId, groupName) {
		return this.db.executeSql("update topic set t_title='" + groupName + "' where t_senderId='" + groupId + "'");
	}

	setGroupName(topicId, groupId, createBy, groupName) {
		let postData = {
			groupId: groupId,
			createBy: createBy,
			groupName: groupName
		}
		return http.post(baseApi + "/group/setName", postData);
	}

	getGroupMember(groupId) {
		let postData = {
			groupId: groupId
		}
		return http.post(baseApi + "/group/getMember", postData);
	}

	/**
	 * 移除小组
	 * @param {*} groupId  小组ID
	 * @param {*} createAlias 创建者ID 别名
	 */
	removeGroup(groupId, createAlias) {
		let postData = {
			groupId: groupId,
			createAlias: createAlias
		};
		return http.post(baseApi + "/group/remove", postData);
	}

	addGroupAlias(groupId, createAlias, aliasItems) {
		let postData = {
			groupId: groupId,
			createAlias: createAlias,
			aliasItems: aliasItems.join(',')
		};
		return http.post(baseApi + "/group/addAlias", postData);
	}

	/**
	 * 移除小组用户
	 * @param {*} groupId 小组ID
	 * @param {*} createAlias  创建者ID 别名
	 * @param {*} aliasItems 数组
	 */
	removeGroupAlias(groupId, createAlias, aliasItems) {
		let postData = {
			groupId: groupId,
			createAlias: createAlias,
			aliasItems: aliasItems.join(',')
		};
		return http.post(baseApi + "/group/removeAlias", postData);
	}

	joinGroup(groupId, alias) {
		let postData = {
			groupId: groupId,
			alias: alias
		};
		return http.post(baseApi + "/group/join", postData);
	}

	leaveGroup(groupId, alias) {
		let postData = {
			groupId: groupId,
			alias: alias
		};
		return http.post(baseApi + "/group/leave", postData);
	}

}
